<?php
namespace app\console\controller;

use think\Db;

//防止执行超时
set_time_limit(0);

/**
 * Class CleanPic
 * @package app\console\controller  清除网站垃圾图片
 */
class CleanPic
{
    protected $_num = 0;  //删除图片的数量
    protected $_server_num = 0;  //数据库全部图片的数量
    protected $_dir = 'uploads';  //图片保存的public下的一级目录
    protected $_database = [
        'hsw9988_com' => ['picUrl', 'thumb_img']
    ];

    /**
     * CleanPic constructor.
     * @param $database $array [数据库名1 => [字段1 , 字段2]]
     * @param $dir $string 文件所在目录 public下的一级目录
     */
    public function __construct($dir = 'uploads')
    {
        $this->_directory = ROOT_PATH . 'public' . DIRECTORY_SEPARATOR . $dir;
        $this->_dir = '/' . $dir;
    }

    /**
     * @return array 返回数据库图片全部数据
     */
    public function get_data()
    {
        if (!is_array($this->_database)) {
            return ['code' => 400, 'message' => '数据库参数不正确'];
        }
        $_dataPic = [];
        foreach ($this->_database as $key => &$item) {
            if (is_numeric($key) || !$item) {
                return ['code' => 400, 'message' => '数据库参数不正确'];
            }
            $find = Db::name($key)->field($item)->select();
            //分解字段
            if (strstr($item, ',')) {
                $item = explode(',', $item);
            }
            foreach ($find as $value) {
                if (is_array($item)) {
                    foreach ($item as $_item) {
                        $_dataPic[] = $value[$_item];
                    }
                } else {
                    $_dataPic[] = $value[$item];
                }
            }
        }
        return $_dataPic;
    }

    /**
     * @param $path array   每次递归的目录
     * @return array 递归对比并删除垃圾文件
     */
    public function circle($path)
    {
        //得到目录下的所有文件夹
        $Dirs = scandir($path);

        foreach ($Dirs as $item) {
            //如果是“.”或者“..”的话则略过
            if (in_array($item, array('.', '..', 'Thumbs.db'))) continue;
            //完整文件名
            $full_name = $path . '/' . $item;
            $full_name = str_replace('\\', '/', $full_name);

            if (!is_dir($full_name) && !is_readable($full_name)) {
                return ['code' => 400, 'message' => '目录不可读或不存在'];
            }

            if (is_dir($full_name)) {   //是文件夹则递归
                $this->circle($full_name);
            } else {
                $itemArr = explode(".", $item);
                //否则把文件名存入临时数组
                $ext = end($itemArr);
                if (!in_array($ext, array('jpg', 'png', 'gif', 'bmp', 'swf', 'flv', 'rar', 'zip', 'ppt', 'doc'))) continue;
                $this->_server_num += 1;
                //清除图片
                if ($this->delete($full_name)) {
                    $this->_num += 1;
                };
            }
        }
        return [$this->_server_num, $this->_num];
    }

    /**
     * @param $full_name string 文件全路径
     * @return array|bool
     */
    public function delete($full_name)
    {
        if (!file_exists($full_name)) {
            return ['code' => 400, 'message' => $full_name . '文件不存在'];
        }
        $pos = strpos($full_name, $this->_dir);
        $finish_name = substr($full_name, $pos);
        $database = $this->get_data();  //数据库全部图片
        if (!in_array($finish_name, $database)) {  //若不在数据库则删除
            if (!is_writable($full_name)) {
                chmod($full_name, 0777);
            }
            if (unlink($full_name)) {
                //判断文件所在目录是否为空,为空则删除
                if (count(scandir(dirname($full_name))) === 2) {
                    rmdir(dirname($full_name));
                }
                return true;
            } else {
                return false;
            }

        }
    }

    /**
     * @return array   清理图片
     */
    public function clean_server()
    {
        if (!is_dir($this->_directory) && !is_readable($this->_directory)) {
            return ['code' => 400, 'message' => '目录不可读或不存在'];
        }
        $result = $this->circle($this->_directory);
        if ($result[1] === 0) {
            return ['code' => 200, 'message' => '服务器暂无垃圾图片'];
        }
        if (($result[0] - $result[1]) == count($this->get_data())) {
            return ['code' => 200, 'message' => '全部删除成功'];
        }
        return ['code' => 400, 'message' => '有残留未删除'];
    }
}